package org.tang.springcloudvv.interceptor;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.logging.jdbc.PreparedStatementLogger;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;

import java.lang.reflect.Proxy;
import java.sql.Statement;
import java.util.Properties;

/**
 * tangfuzhong
 * mybatis插件，把sqlId关联到慢sql记录
 */

@Intercepts({
        @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})
})
public class MybatisSqlV2Interceptor implements Interceptor {
    static int MAPPED_STATEMENT_INDEX = 0;

    @Override
    public Object intercept(final Invocation invocation) throws Throwable {
        Object[] queryArgs = invocation.getArgs();
        Object firstArg = queryArgs[MAPPED_STATEMENT_INDEX];
        /*
        tang:
        以前的版本，拦截到StatementHandler的query,第一个参数就是MappedStatement
        但是现在新版本不是了：
        调试发现这个参数并不是MappedStatement
        在这个代理类的h里可以看到PreparedStatementLogger，接着可以拿到里面的Statement
        进一步的问题，是无法拿出h
         */
        //com.sun.proxy.$Proxy124
        String classProxy = firstArg.getClass().getName();
        //java.lang.reflect.Proxy
        String superClass = firstArg.getClass().getSuperclass().getName();
        if (firstArg instanceof Proxy)
        {
            Proxy proxy = (Proxy)firstArg;
            Object h = new Object();
            //h = proxy.h; 无法获取,因此此路不通
            if (h instanceof PreparedStatementLogger)
            {
                PreparedStatementLogger preparedStatementLogger = (PreparedStatementLogger)queryArgs[MAPPED_STATEMENT_INDEX];
                Statement statement = preparedStatementLogger.getPreparedStatement();
                String sql = statement.toString();
            }
        }


        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
